#include <stm32f1xx_hal.h>
#include <cstdlib>
#include <ws2812.hpp>
#include <fireworks.h>

#define RANDFLOAT() (float(rand()) / RAND_MAX)
#define MAXSPEED 2.5

extern WS2812 strip;

struct Particle {
    CHSV color;
    float position;
    float speed;

    void init() {
        color = CHSV(RANDFLOAT() * 255, 255, 255);
        position = RANDFLOAT() * WS_NLEDS;
        speed = RANDFLOAT() * 2 * MAXSPEED;
        speed -= MAXSPEED;
    }

    void update() {
        position += speed;
        color.v *= 0.98;
        if ((position >= WS_NLEDS) || (position < 0))
            position = -1;
    }
} particles[20];

void fireworks_init() {
    strip.init();
    strip.clear();
    for (auto &particle :particles)
        particle.init();
}

void fireworks_render() {
    strip.fade(0.9);
    static uint32_t last_init = HAL_GetTick();
    static int nparticles = 1 + RANDFLOAT() * 19;
    uint32_t duration = HAL_GetTick() - last_init;
    if (duration < 1500) {
        for (int i = 0; i < nparticles; i++) {
            auto &particle = particles[i];
            if (particle.position < 0)
                continue;
            strip.drawPixel(particle.position, 1, CRGB(particle.color));
            particle.update();
        }
    } else {
        for (auto &particle :particles) {
            particle.init();
        }
        last_init = HAL_GetTick();
        nparticles = 1 + RANDFLOAT() * 19;
    }
}

void fireworks_display() {
    strip.render();
}

